#!/usr/bin/python
# -*- coding: utf-8 -*-
'''
@author:atuo.cn
'''

from tkinter import *
from tkinter.ttk import *
from tkinter.filedialog import askopenfilename
from tkinter.messagebox import *
from os import path

from assembler import parser, render
from dialogs.maindialog_layout import ApplicationLayout
from dialogs.tooltip import CallbackToolTip
from dialogs.patterndialog import PatternDialog
from dialogs.sectiondialog import SectionDialog
from dialogs.hintsdialog import HintsDialog
from dialogs.settingsdialog import SettingsDialog

class Application(ApplicationLayout):
    def __init__(self, master, wmtitle):
        ApplicationLayout.__init__(self, master, wmtitle)

    def onLoad(self):
        #tooltip
        self.tooltip=CallbackToolTip(self.treeviewSections, self.showTooltip)
        
        self.sectionRe.set(PatternDialog.PATTERNS[0])
        self.captureBookTitle.set("FILENAME")
        self.titleLen.set(HintsDialog.HINT_OPTS["MaxSectionTitleLen"])
        self.bookTitleRe.set(r"[<《『](.+)[>》』]")
        self.authorRe.set(r"^作者[:：\s]\s*(.+)")
        self.dropHtmlRe.set(r"\<MARQUEE.+?\>.+?\</MARQUEE\>")
        self.filename = ""
        self.hint_opts = HintsDialog.HINT_OPTS
    
    def statusReady(self):
        self.statusBar.show_status("Ready")
        
    def statusChapter(self, index=None):
        chapter ="chapter:%5d"%index if index else ""
        self.statusMessage(chapter,"Total chapter:%5d"%len(self.book.sections),index=2)        
        
    def statusMessage(self, *messages, index=0):
        self.statusBar.show_status(*messages, index=index)
        
    def loadSectionView(self):
        self.treeviewSections.delete(*self.treeviewSections.get_children())
        for section in self.book.sections:
            raw_title= section.rawTitle
            if section.title==raw_title: 
                raw_title=""
            self.treeviewSections.insert(
                "",
                "end",
                tag="CONTENT",
                values=(section.title, section.lineNo, raw_title)
            )
        self.statusChapter()

    def updateView(self):
        self.loadSectionView()
        if self.book.captureBookTitle:
            self.bookTitle.set(self.book.bookTitle)
        if self.book.captureAuthor:
            self.bookAuthors.set(','.join(self.book.authors))
        self.statusReady()
        
    def showTooltip(self, tipwindow, pointer):
        listbox = Listbox(tipwindow, background="#ffffe0")
        listbox.pack()
        row=self.treeviewSections.identify_row(pointer[1])
        if not row: return False
        
        index=self.treeviewSections.index(row)
        width=0
        for text in self.book.sections[index].rawText:
            s=text[:54] + ("......" if len(text)>=54 else "")
            listbox.insert(END, s)
            width=max((width, len(s)))
        listbox.config(width = min((width*2, 120)))    
        listbox.itemconfig(self.book.sections[index].rawTitleIndex,
                           foreground="#22b14c")
        return True
        
    def initParser(self):
        book = parser.TextBook()
        book.lang = self.settings["lang"]
        book.encoding = self.settings["encoding"]        
        book.sectionRe = self.sectionRe.get()
        book.hints= self.hint_opts
        book.cover = ""
        book.maincss = ""
        
        book.captureBookTitle=(self.captureBookTitle.get() != "FILENAME")
        book.bookTitleRe=self.bookTitleRe.get()
        book.captureAuthor=self.captureAuthors.get()
        book.authorRe=self.authorRe.get()
        book.dropHtml=self.dropHtml.get()
        book.dropHtmlRe=self.dropHtmlRe.get()
        book.includemeta=self.settings["IncludeIntro"]
        book.file =self.filename
        #book.contentRange=(6,274)
        return book
        
    def do_open(self):
        if not self.filename : return
        
        dirname, basename = path.split(self.filename)
        wm_title="%s [%s]"%(self.wmtitle, basename)
        self.winfo_toplevel().wm_title(wm_title)
        self.statusMessage("Open file...","Filename: %s"%self.filename)
        
        majorname = path.splitext(basename)[0]
        self.outDir = path.join(dirname, majorname)
        count = 0
        while path.isfile(self.outDir):
            count+=1
            self.outDir = path.join(dirname, "%s~%d"%(majorname,count))
        if self.captureBookTitle.get() == "FILENAME": self.bookTitle.set(majorname)

        self.book=self.initParser()
        self.book.parseBook()
        self.updateView()
        
    #Event Handlers
    def open_file(self):
        try:
            self.filename = askopenfilename()
            self.do_open()
        except Exception as ex:
            showinfo(self.wmtitle, str(ex))        
    
    def to_epub(self):
        try:
            self._convert(render.EPubRender())
        except Exception as ex:
            showinfo(self.wmtitle, str(ex))        
    
    def to_mobi(self):
        try:
            self._convert(render.MobiRender(self.settings["kindlegen"],
                                            self.settings["kindlearg"]))
        except Exception as ex:
            showinfo(self.wmtitle, str(ex))        
                      
    def _convert(self, render):
        msg = None
        if not self.filename:
            msg = "Please open a file first!"
        if not self.bookTitle.get():
            msg = "Please set the book title!"

        if msg:
            showinfo(self.wmtitle,msg)
            return
        
        self.statusMessage("Converting...")
        self.book.bookTitle = self.bookTitle.get()
        self.book.authors = self.bookAuthors.get().split(",")
        self.book.make(render, self.outDir)
        
        showinfo(self.wmtitle, "Convert over!")
        self.statusReady()
            
    def do_popup(self,event):
        self.popupmenu.tk_popup(event.x_root, event.y_root)
                
    def delete_section(self):
        items=self.treeviewSections.selection()
        if not items:
            showinfo(self.wmtitle,"Please select items")
            return
        for item in items:
            index=self.treeviewSections.index(item)
            
            section=self.book.sections.pop(index)
            if index>0:
                current=self.book.sections[index-1]
                #get the title line raw text.
                if self.treeviewSections.tag_has("CONTENT", item):
                    current.text.append(section.rawTitle)
                current.text.extend(section.text)
            self.treeviewSections.delete(item)
        self.statusChapter()
        
    def insert_section(self):
        items=self.treeviewSections.selection()
        if not items or len(items)> 1:
            showinfo(self.wmtitle,"Please select an item")
            return
        
        index=self.treeviewSections.index(items[0])
        
        section=parser.ContentSection()
        section.title="New Section"
        self.book.sections.insert(index, section)
        self.treeviewSections.insert(
            "", 
            index,
            tag="CONTENT",
            values=(section.title, section.lineNo, "")
        )
        self.statusChapter()
        
    def edit_section_cmd(self):
        items=self.treeviewSections.selection()
        if not items or len(items)> 1:
            showinfo(self.wmtitle,"Please select an item")
            return
        self.edit_section_row(items[0])
                
    def section_selected(self,event):
        items=self.treeviewSections.selection()
        if not items or len(items) > 1:
            index=None
        else:
            index=self.treeviewSections.index(items[0])+1
        self.statusChapter(index)
                           
    def select_pattern(self):
        dialog=PatternDialog(self, self.wmtitle)
        if dialog.selected:
            self.sectionRe.set(dialog.selected)
            
    def edit_section(self, event):
        row=self.treeviewSections.identify_row(event.y)
        self.edit_section_row(row)
    
    def edit_section_row(self, row):
        if not row or not self.book: return False
        
        index=self.treeviewSections.index(row)
        section=self.book.sections[index]
        SectionDialog(self, self.wmtitle, section)
        self.treeviewSections.set(row, "Title", section.title)

    def reopen(self):
        self.do_open()
    
    def advance_hints(self):
        hints=self.hint_opts
        dialog=HintsDialog(self, self.wmtitle, hints)
        self.hint_opts=dialog.hints
        
    def edit_settings(self):
        print("edit settings")
        print(*["%s: %s"%(k,self.settings[k]) for k in self.settings])
        dialog=SettingsDialog(self, self.wmtitle,self.settings)
        self.settings=dialog.settings
        